<?php
namespace App\GraphQL\Mutations\DeviceOrder;

use App\Models\DeviceOrder;
use GraphQL\Type\Definition\ResolveInfo;
use Illuminate\Support\Facades\Validator;
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Kra8\Snowflake\Snowflake;
use App\Models\GlobalStatistical;
use App\Models\AgentStatistical;
use App\Models\MerchantStatistical;
use App\Models\RepairerStatistical;
use App\Models\DistributorStatistical;
use App\Models\RepairerDeviceGroup;

class Receipt
{

    /**
     * Return a value for the field.
     *
     * @param null $rootValue
     *            Usually contains the result returned from the parent field. In this case, it is always `null`.
     * @param mixed[] $args
     *            The arguments that were passed into the field.
     * @param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context
     *            Arbitrary data that is shared between all fields of a single query.
     * @param \GraphQL\Type\Definition\ResolveInfo $resolveInfo
     *            Information about the query itself, such as the execution state, the field name, path to the field from the root, and more.
     * @return mixed
     */
    public function __invoke($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
    {
        DB::transaction(function () use ($args) {
            $authUser = auth()->user();
            $data = $args['input'];
            $id = $args['id'];
            $deviceOrder = $this->validate($id, $data);
            $data['receipt_time'] = Carbon::now();
            $data['status'] = 'COMPLETE';
            $data['receipt_user_id'] = auth()->user()->id;
            $deviceOrder->update($data);
            $devices = $deviceOrder->devices;
            $deviceLogs = $devices->map(function ($item) use (&$authUser) {
                $temp = [
                    'id' => resolve(Snowflake::class)->next(),
                    'level' => 'GREEN',
                    'user_id' => $authUser->id,
                    'device_id' => $item['id'],
                    'content' => '安装',
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now()
                ];
                return $temp;
            });
            DB::table('device_logs')->insert($deviceLogs->toArray());
            $deviceCount = $devices->count();
            // 更新全局设备统计
            $globalStatistical = GlobalStatistical::first();
            if (! $globalStatistical) {
                $globalStatistical = GlobalStatistical::create();
            }
            $globalStatistical->increment('use_device_count', $deviceCount);
            $globalStatistical->increment('device_count', $deviceCount);
            // 更新代理商(群组创建者)设备统计
            $agentStatistical = AgentStatistical::firstOrCreate([
                'user_id' => $deviceOrder->device_group->user_id
            ]);
            $agentStatistical->increment('link_device_count', $deviceCount);
            // 更新终端伙伴设备统计
            if ($deviceOrder->device_group->merchant) {
                $merchantStatistical = MerchantStatistical::firstOrCreate([
                    'user_id' => $deviceOrder->device_group->merchant->id
                ]);
                $merchantStatistical->increment('link_device_count', $deviceCount);
            }
            // 更新维修方统计
            $repairerStatistical = RepairerStatistical::firstOrCreate([
                'user_id' => $authUser->id
            ]);
            $repairerStatistical->increment('today_install_count', $deviceCount);
            $repairerStatistical->increment('link_device_count', $deviceCount);
            // 判断是否维护已经在维护该群组
            $repairGroups = $authUser->repair_device_groups;
            if (! $repairGroups) {
                if ($repairGroups->whereIn('id', $deviceOrder->device_group->id)->count() <= 0) {
                    $authUser->repair_device_groups()->create([
                        'device_group_id' => $deviceOrder->device_group->id
                    ]);
                    $repairerStatistical->increment('link_group_count');
                }
            } else {
                RepairerDeviceGroup::create([
                    'device_group_id' => $deviceOrder->device_group->id,
                    'repairer_user_id' => auth()->user()->id
                ]);
                $repairerStatistical->increment('link_group_count');
            }

            // 更新分销商统计
            $distributors = $deviceOrder->device_group->members()
                ->where('role', 'DISTRIBUTOR')
                ->get();
            $distributors->map(function ($distributor) use ($deviceCount) {
                $distributorStatistical = DistributorStatistical::firstOrCreate([
                    'user_id' => $distributor->user_id
                ]);
                $distributorStatistical->increment('link_device_count', $deviceCount);
            });
        });
        return [
            'status' => '200',
            'message' => '付款成功'
        ];
    }

    public function validate($id, $data)
    {
        $rules = [
            'receipt_voucher' => [
                'required'
            ]
        ];
        $messages = [
            'receipt_voucher.required' => '收货凭证不能为空'
        ];
        $validate = Validator::make($data, $rules, $messages);
        if ($validate->fails()) {
            throw new \InvalidArgumentException($validate->messages()->first());
        }
        $old = DeviceOrder::find($id);
        if (! $old) {
            throw new \Exception('订单不存在!');
        }
        if ($old->status !== 'WAIT_RECEIPT') {
            throw new \Exception('订单未出厂,无法操作!');
        }
        if ($old->status === 'COMPLETE') {
            throw new \Exception('订单已经收货,无法操作!');
        }
        return $old;
    }
}
